Systems Managerのパラメータストアを更新したあと、Lambdaを再デプロイしないと内容が反映されなかった話
AWS SAMやCloudFormationでsAWS Systems Managerのパラメータストアを使っている方は多いと思います。 何らかの値をLambdaの環境変数として渡せば、templateファイル自体に内容が記載されないため、GitHub等でPublicなリポジトリにできたりします。
そんなパラメータストアですが、内容を変更したあと、Lambdaを再デプロイしないと値が反映されませんでした。という話です。
パラメータストアに値を追加
下記コマンドでSSM(AWS Systems Manager)のパラメータストアに適当な値を追加します。
$ aws ssm put-parameter \ --type 'String' \ --name '/Hoge/Message' \ --value 'This is a pen.' { "Version": 1, "Tier": "Standard" }
AWS SAMで適当なLambdaを作成する
テンプレートファイルを修正
SSMパラメータストアから/Hoge/Message
の値を取得し、Lambdaの環境変数MESSAGE
に設定しています。
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: ssm-parameter-sample Parameters: Message: Type: AWS::SSM::Parameter::Value<String> Resources: HelloWorldFunction: Type: AWS::Serverless::Function Properties: CodeUri: hello_world/ Handler: app.lambda_handler Runtime: python3.7 Environment: Variables: MESSAGE: !Ref Message Timeout: 5 Events: HelloWorld: Type: Api Properties: Path: /hello Method: get Outputs: HelloWorldApi: Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
Lambdaコードを作成
Lambdaの環境変数MESSAGE
の内容をAPIのResponseBodyとしています。
import json import os MESSAGE = os.environ['MESSAGE'] def lambda_handler(event, context): return { 'statusCode': 200, 'body': json.dumps({ 'message': MESSAGE, }), }
デプロイする
下記コマンドでビルド&デプロイします。parameter-overrides
には、SSMパラメータストアのKey名を与えています。
$ sam build $ sam package \ --output-template-file packaged.yaml \ --s3-bucket hoge-sam-bucket $ sam deploy \ --template-file packaged.yaml \ --stack-name Ssm-Parameter-Sample-Stack \ --capabilities CAPABILITY_NAMED_IAM \ --no-fail-on-empty-changeset \ --parameter-overrides \ Message=/Hoge/Message
動作確認する(初回)
APIエンドポイントを取得する
下記コマンドでAPIエンドポイントを取得します。
$ aws cloudformation describe-stacks \ --stack-name Ssm-Parameter-Sample-Stack \ --query 'Stacks[].Outputs' [ [ { "OutputKey": "HelloWorldApi", "OutputValue": "https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/" } ] ]
APIにアクセスする
最初にSSMパラメータストアに登録した内容が返ってきました。
$ curl https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/ {"message": "This is a pen."}
動作確認する(パラメータストアを更新した)
パラメータストアの内容を更新する
下記コマンドでSSMパラメータストアの内容を更新します。overwrite
オプションを付与しています。
$ aws ssm put-parameter \ --overwrite \ --type 'String' \ --name '/Hoge/Message' \ --value 'This is a banana.' { "Version": 2, "Tier": "Standard" }
APIにアクセスする
SSMパラメータストアを更新しましたが、APIの応答には反映されていません。
$ curl https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/ {"message": "This is a pen."}
Lambdaの様子
マネジメントコンソールでLambdaを確認すると、環境変数は更新されていません。
動作確認する(再デプロイした)
再デプロイする
同じコマンドで再デプロイします。
$ sam build $ sam package \ --output-template-file packaged.yaml \ --s3-bucket hoge-sam-bucket $ sam deploy \ --template-file packaged.yaml \ --stack-name Ssm-Parameter-Sample-Stack \ --capabilities CAPABILITY_NAMED_IAM \ --no-fail-on-empty-changeset \ --parameter-overrides \ Message=/Hoge/Message
APIにアクセスする
APIの応答には反映されました!
$ curl https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/ {"message": "This is a banana."}
Lambdaの様子
マネジメントコンソールでLambdaを確認すると、環境変数は更新されました!
さいごに
改めて考えてみると「そうですよね」としか言えないですが、知らなければ地味にハマりそうです。 SSMパラメータストアの内容を即時反映したい場合は、Lambdaの環境変数を使わずにコードで毎回取得すると良さそうですね。